package com.woniu.his.bms.service.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.woniu.his.bms.common.enums.BmsStatusEnums;
import com.woniu.his.bms.infra.model.BillsRecord;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.woniu.his.bms.common.BmsResultCode;
import com.woniu.his.bms.infra.model.InvoiceExp;
import com.woniu.his.bms.infra.model.InvoiceRecord;
import com.woniu.his.bms.infra.mapper.InvoiceRecordMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.woniu.his.bms.service.BillsRecordService;
import com.woniu.his.bms.service.InvoiceRecordService;
import com.woniu.his.bms.service.dto.QueryAmountForStaffDto;
import com.woniu.his.dms.client.CaseHistoryClient;
import com.woniu.his.dms.client.result.CaseHistoryResult;
import com.woniu.his.result.Result;
import com.woniu.his.bms.infra.model.OperatorSettleRecord;
import com.woniu.his.bms.service.*;
import com.woniu.his.bms.service.dto.BmsInvoiceDto;
import com.woniu.his.exception.HisException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 发票记录 服务实现类
 * </p>
 *
 * @author chenbo
 * @since 2022-11-29
 */
@Service
@Slf4j
public class InvoiceRecordServiceImpl extends ServiceImpl<InvoiceRecordMapper, InvoiceRecord> implements InvoiceRecordService {

    @Resource
    private BillsRecordService billsRecordService;

    @Resource
    private CaseHistoryClient caseHistoryClient;

    @Override
    public QueryAmountForStaffDto queryAmountForStaff(Long staffId, String date) {

        SimpleDateFormat s=new SimpleDateFormat("yyyy-MM-dd");

        DateTime startTime = DateUtil.parse(date);
        Calendar calendar=new GregorianCalendar();
        calendar.setTime(startTime);
        calendar.add(Calendar.DATE, 1);
        Date endTime=DateUtil.parse(s.format(calendar.getTime()));

        List<InvoiceRecord> list = list();
        if (list.size()<= 0) return null;
        //根据时间筛选一部分
        List<InvoiceRecord> invoices = new ArrayList<>();
        List<Long> ids = new ArrayList<>();
        for (InvoiceRecord invoiceRecord : list) {
            if (invoiceRecord.getCreateTime().after(startTime)&&invoiceRecord.getCreateTime().before(endTime)) {
                invoices.add(invoiceRecord);
                ids.add(invoiceRecord.getBillId());
            }
        }
        List<BillsRecord> billsRecords = billsRecordService.listByIds(ids);
        if (billsRecords.size()<=0) return null;
        //满足某staff的账单集合  最终账单集合
        List<BillsRecord> br=new ArrayList<>();
        List<Long> brIds = new ArrayList<>();

        System.out.println("billsRecord"+ billsRecords.toString());

        for (BillsRecord billsRecord : billsRecords) {
            Result<CaseHistoryResult> result = caseHistoryClient.queryById(billsRecord.getCaseHistoryId());
            System.out.println("result："+result.toString());
            if (result.isSuccess()){
                if (result.getData().getStaffId().equals(staffId)){
                    br.add(billsRecord);
                    brIds.add(billsRecord.getId());
                }
            }
        }
        QueryWrapper<InvoiceRecord> wrapper=new QueryWrapper<>();
        wrapper.in("bill_id", brIds);
        //最终发票集合
        System.out.println(brIds);
        List<InvoiceRecord> recordList = list(wrapper);
        System.out.println("-------------");
        if (recordList.size()<=0) return null;

        //成药总金额
        BigDecimal medicineAmount= new BigDecimal(0);
        //草药总金额
        BigDecimal herbalAmount = new BigDecimal(0);
        //检查总金额
        BigDecimal checkAmount = new BigDecimal(0);
        //检验总金额
        BigDecimal testAmount = new BigDecimal(0);
        //处置总金额
        BigDecimal dispositionAmount = new BigDecimal(0);
        //挂号总金额
        BigDecimal registrationAmount = new BigDecimal(0);
        //总金额
        BigDecimal totalAmount = new BigDecimal(0);
        //挂号数量
        Long registrationNum= new Long(0);
        //执行检查的金额
        BigDecimal excuteCheckAmount = new BigDecimal(0);
        //执行检验的金额
        BigDecimal excuteTestAmount = new BigDecimal(0);
        //执行处置的金额
        BigDecimal excuteDispositionAmount = new BigDecimal(0);
        //执行的总人数
        Long excuteRegistrationNum= new Long(0);

        for (InvoiceRecord invoiceRecord : recordList) {
            BillsRecord status = billsRecordService.getById(invoiceRecord.getBillId());
            if (!status.getStatus().equals(BmsStatusEnums.DELETE.getCode())){
                if (status.getType().equals(BmsStatusEnums.MEDICINE.getCode())){
                    medicineAmount=medicineAmount.add(invoiceRecord.getAmount());
                }
                if (status.getType().equals(BmsStatusEnums.HERBAL.getCode())){
                    herbalAmount = herbalAmount.add(invoiceRecord.getAmount());
                }
                if (status.getType().equals(BmsStatusEnums.CHECK.getCode())){
                    checkAmount = checkAmount.add(invoiceRecord.getAmount());
                    if (status.getStatus().equals(BmsStatusEnums.NOT_REGIST.getCode())||status.getStatus().equals(BmsStatusEnums.EXCUTED.getCode())){
                        excuteCheckAmount= excuteCheckAmount.add(invoiceRecord.getAmount());
                    }
                }
                if (status.getType().equals(BmsStatusEnums.TEST.getCode())){
                    testAmount = testAmount.add(invoiceRecord.getAmount());
                    if (status.getStatus().equals(BmsStatusEnums.NOT_REGIST.getCode())||status.getStatus().equals(BmsStatusEnums.EXCUTED.getCode())){
                        excuteTestAmount= excuteTestAmount.add(invoiceRecord.getAmount());
                    }
                }
                if (status.getType().equals(BmsStatusEnums.DISPOSITION.getCode())){
                    dispositionAmount = dispositionAmount.add(invoiceRecord.getAmount());
                    if (status.getStatus().equals(BmsStatusEnums.NOT_REGIST.getCode())||status.getStatus().equals(BmsStatusEnums.EXCUTED.getCode())){
                        excuteDispositionAmount= excuteDispositionAmount.add(invoiceRecord.getAmount());
                    }
                }
                if (status.getType().equals(BmsStatusEnums.REGISTRATION.getCode())){
                    registrationAmount = registrationAmount.add(invoiceRecord.getAmount());
                    registrationNum++;
                    if (status.getStatus().equals(BmsStatusEnums.NOT_REGIST.getCode())||status.getStatus().equals(BmsStatusEnums.EXCUTED.getCode())){
                        excuteRegistrationNum++;
                    }
                }
                totalAmount= totalAmount.add(invoiceRecord.getAmount());
            }
        }
        QueryAmountForStaffDto queryAmountForStaffDto=new QueryAmountForStaffDto();
        queryAmountForStaffDto.setMedicineAmount(medicineAmount);
        queryAmountForStaffDto.setHerbalAmount(herbalAmount);
        queryAmountForStaffDto.setCheckAmount(checkAmount);
        queryAmountForStaffDto.setDispositionAmount(dispositionAmount);
        queryAmountForStaffDto.setRegistrationAmount(registrationAmount);
        queryAmountForStaffDto.setTestAmount(testAmount);
        queryAmountForStaffDto.setAmount(totalAmount);
        queryAmountForStaffDto.setRegistrationNum(registrationNum);
        queryAmountForStaffDto.setExcuteCheckAmount(excuteCheckAmount);
        queryAmountForStaffDto.setExcuteTestAmount(excuteTestAmount);
        queryAmountForStaffDto.setExcuteDispositionAmount(excuteDispositionAmount);
        queryAmountForStaffDto.setExcuteNum(excuteRegistrationNum);

        return queryAmountForStaffDto;
    }


    @Resource
    private InvoiceExpService invoiceExpService;

    @Resource
    private OperatorSettleRecordService op;



    /**
     *  发票补打 上一张发票打的有误 重新打
     * @param newInvoiceNo
     * @param billId
     * @return
     */
    @Override
    public boolean supplementPrintInvoice(Long newInvoiceNo, Long billId) {
        // 找出账单对应的所有发票 最近开的一张
        InvoiceRecord invoiceRecord = list(new QueryWrapper<InvoiceRecord>().eq("bill_id", billId).orderByDesc("create_time")).get(0);
        if (invoiceRecord == null) {
            throw new HisException(BmsResultCode.NOT_FUND_LATEST_INVOICE);
        }
        invoiceRecord.setInvoiceNo(newInvoiceNo);
        updateById(invoiceRecord);
        return true;
    }

    /**
     * 重打发票
     *
     * @param newInvoiceNo
     * @param oldInvoiceNo
     * @return
     */
    @Override
    public boolean reprintInvoice(Long newInvoiceNo, Long oldInvoiceNo) {

        InvoiceRecord invoiceRecord = getOne(new QueryWrapper<InvoiceRecord>().eq("invoice_no", oldInvoiceNo));
        if (invoiceRecord == null) {
            throw new HisException(BmsResultCode.NOT_FUND_LATEST_INVOICE);
        }
        //旧发票设置状态为重打
        invoiceRecord.setFreezeStatus("REPRINT");
        updateById(invoiceRecord);
        //新发票开新发票号并且保存
        InvoiceRecord newBmsInvoiceRecord = new InvoiceRecord();
        BeanUtils.copyProperties(invoiceRecord, newBmsInvoiceRecord);//???? 是否会复制id 不会
        log.info("新发票信息:{}",newBmsInvoiceRecord);

        newBmsInvoiceRecord.setInvoiceNo(newInvoiceNo);
        newBmsInvoiceRecord.setFreezeStatus("NORMAL");
        newBmsInvoiceRecord.setAssociateId(invoiceRecord.getId());
        newBmsInvoiceRecord.setCreateTime(new Date());
        save(newBmsInvoiceRecord);
        return true;
    }


    /**
     * 查询发票
     *
     * @param cashierId
     * @param startDatetime
     * @param endDatetime
     * @return
     */
    @Override
    public List<BmsInvoiceDto> queryInvoiceInfo(Long cashierId, Date startDatetime, Date endDatetime) {

        List<InvoiceRecord> list = list(new QueryWrapper<InvoiceRecord>().eq("operator_id", cashierId).gt("create_time", startDatetime)
                .lt("create_time", endDatetime));
        if (list.size() <= 0) {
            throw new HisException(BmsResultCode.NOT_FUND_LATEST_INVOICE);
        }
        return list.stream().map(o -> {
            BmsInvoiceDto bmsInvoiceDto = BeanUtil.copyProperties(o, BmsInvoiceDto.class);
            bmsInvoiceDto.setName(invoiceExpService.getById(o.getInvoiceId()).getName());
            OperatorSettleRecord operatorSettleRecord = op.getById(o.getSettlementCatId());
            if (operatorSettleRecord!=null) {
                bmsInvoiceDto.setSettlementCatName(operatorSettleRecord.getVerifyStatus());
            }
            return bmsInvoiceDto;
        }).collect(Collectors.toList());
    }

    /**
     * 根据日记记录查询发票
     * @param settleRecordId
     * @return
     */
    @Override
    public List<BmsInvoiceDto> queryInvoiceInfoBySettleId(Long settleRecordId) {

        List<InvoiceRecord> list = list(new QueryWrapper<InvoiceRecord>().eq("settle_record_id", settleRecordId));
        if (list.isEmpty()) {
            throw new HisException(BmsResultCode.NOT_FUND_LATEST_INVOICE);
        }
        return list.stream().map(o -> {
            BmsInvoiceDto bmsInvoiceDto = BeanUtil.copyProperties(o, BmsInvoiceDto.class);
            bmsInvoiceDto.setName(invoiceExpService.getById(o.getInvoiceId()).getName());
            OperatorSettleRecord operatorSettleRecord = op.getById(o.getSettlementCatId());
            //如果发票已经日结
            if (operatorSettleRecord!=null) {
                bmsInvoiceDto.setSettlementCatName(operatorSettleRecord.getVerifyStatus());
            }
            return bmsInvoiceDto;
        }).collect(Collectors.toList());
    }





}
